﻿namespace MicroCloud.Entity.Database
{
    /// <summary>
    /// 事务通知过程
    /// </summary>
    [Description("事务通知过程")]
    public class SP_TransactionNotification : ProcedureHandlerBase
    {
        /// <summary>
        /// 初始化一个事务通知过程 <see cref="SP_TransactionNotification"/> 的新实例
        /// </summary>
        /// <param name="serviceProvider">服务提供者</param>
        public SP_TransactionNotification(IServiceProvider serviceProvider)
            : base(serviceProvider)
        { }

        /// <summary>
        /// 获取 是否应用所有的数据上下文
        /// <para>默认 false，如果为 true，则忽略 DbContextTypes 属性。</para>
        /// </summary>
        public override bool AllDbContext => false;

        #region 方法
        /// <summary>
        /// 获取名称
        /// </summary>
        /// <param name="databaseType">数据库类型</param>
        /// <returns>名称字符串</returns>
        protected override string GetName(DatabaseType databaseType)
        {
            var name = string.Empty;
            switch (databaseType)
            {
                case DatabaseType.Sqlite:
                    break;
                case DatabaseType.MySql:
                case DatabaseType.SqlServer:
                case DatabaseType.PostgreSql:
                case DatabaseType.Oracle:
                    name = "SP_TransactionNotification";
                    break;
            }
            return name;
        }
        
        /// <summary>
        /// 获取创建脚本
        /// </summary>
        /// <param name="databaseType">数据库类型</param>
        /// <returns>创建脚本字符串</returns>
        protected override string GetCreateScript(DatabaseType databaseType)
        {
            var script = string.Empty;
            switch (databaseType)
            {
                case DatabaseType.Sqlite:
                    break;
                case DatabaseType.MySql:
                    script = @$"CREATE PROCEDURE {GetName(databaseType)} (
entity_name VARCHAR(512),	        -- 实体名称
entity_type_name VARCHAR(1024),	    -- 实体类型名称
operate_type INT,	                -- 操作类型（操作类型：[1]查询；[2]新增；[3]更新；[4]删除）
db_schema VARCHAR(256),	            -- 数据库架构
db_object_name VARCHAR(256),	    -- 数据库对象名称
db_object_type INT,	                -- 数据库对象类型（数据库对象类型：[1]数据表；[2]数据视图；[3]函数；[4]存储过程；[5]触发器）
db_object_key_field VARCHAR(256),	-- 主键字段
db_object_key_value VARCHAR(256),	-- 主键值
db_object_content LONGTEXT	        -- 数据库对象内容，JSON格式
)
BEGIN
	DECLARE code INT DEFAULT 0;             -- 操作返回编号，当 code<>0 时，系统将阻止提交，并返回 message 内容
	DECLARE message LONGTEXT DEFAULT 'OK';  -- 操作返回消息

	--------------------------------------------------------------------------------------------------------------------------------
	--	在分割线下方增加您的逻辑代码，并在判定 code<>0 时，使用 SELECT code,message 语句返回。
	--------------------------------------------------------------------------------------------------------------------------------

	--SELECT json_extract(db_object_content,'$.JsonField1') AS `Field1`;

	--------------------------------------------------------------------------------------------------------------------------------
	--	返回操作结果。
	--------------------------------------------------------------------------------------------------------------------------------
    SELECT code,message;
END;";
                    break;
                case DatabaseType.SqlServer:
                    script = @$"CREATE PROCEDURE {GetName(databaseType)}
@entity_name NVARCHAR(512),     	-- 实体名称
@entity_type_name NVARCHAR(1024),	-- 实体类型名称
@operate_type INT,	                -- 操作类型（操作类型：[1]查询；[2]新增；[3]更新；[4]删除）
@db_schema NVARCHAR(256),	        -- 数据库架构
@db_object_name NVARCHAR(256),	    -- 数据库对象名称
@db_object_type INT,	            -- 数据库对象类型（数据库对象类型：[1]数据表；[2]数据视图；[3]函数；[4]存储过程；[5]触发器）
@db_object_key_field NVARCHAR(256),	-- 主键字段
@db_object_key_value NVARCHAR(256),	-- 主键值
@db_object_content NVARCHAR(MAX)	-- 数据库对象内容，JSON格式
AS
BEGIN
	DECLARE @code INT = 0;                  -- 操作返回编号，当 @code<>0 时，系统将阻止提交，并返回 @message 内容
	DECLARE @message NVARCHAR(MAX) = 'OK';  -- 操作返回消息

	--------------------------------------------------------------------------------------------------------------------------------
	--	在分割线下方增加您的逻辑代码，并在判定 code<>0 时，使用 SELECT code,message 语句返回。
	--------------------------------------------------------------------------------------------------------------------------------

	--print iif(isjson(@db_object_content) > 0, 'OK', 'NO');
	--SELECT T0.*
	--FROM OPENJSON(@db_object_content)
	--WITH (
	--	Field1 NVARCHAR(20) '$.JsonField1'
	--) T0;

	--------------------------------------------------------------------------------------------------------------------------------
	--	返回操作结果。
	--------------------------------------------------------------------------------------------------------------------------------
    SELECT @code,@message;
END";
                    break;
                case DatabaseType.PostgreSql:
                    script = @$"CREATE OR REPLACE PROCEDURE {GetName(databaseType)} (
entity_name character varying(512),	-- 实体名称
entity_type_name varchar(1024),	    -- 实体类型名称
operate_type integer,	            -- 操作类型（操作类型：[1]查询；[2]新增；[3]更新；[4]删除）
db_schema varchar(256),	            -- 数据库架构
db_object_name varchar(256),	    -- 数据库对象名称
db_object_type integer,	            -- 数据库对象类型（数据库对象类型：[1]数据表；[2]数据视图；[3]函数；[4]存储过程；[5]触发器）
db_object_key_field varchar(256),	-- 主键字段
db_object_key_value varchar(256),	-- 主键值
db_object_content text	            -- 数据库对象内容，JSON格式
)
LANGUAGE 'plpgsql'
AS $BODY$
	declare code integer;   -- 操作返回编号，当 code<>0 时，系统将阻止提交，并返回 message 内容
	declare message text;   -- 操作返回消息
BEGIN
    code = 0;
  	message = '';

	--------------------------------------------------------------------------------------------------------------------------------
	--	在分割线下方增加您的逻辑代码，并在判定 code<>0 时，使用 SELECT code,message 语句返回。
	--------------------------------------------------------------------------------------------------------------------------------

	--SELECT db_object_content->>'JsonField1' as `Field1`;

	--------------------------------------------------------------------------------------------------------------------------------
	--	返回操作结果。
	--------------------------------------------------------------------------------------------------------------------------------
    SELECT code,message;
END;
$BODY$;";
                    break;
                case DatabaseType.Oracle:
                    script = @$"create or replace procedure {GetName(databaseType)} (
entity_name NVARCHAR2(512),	-- 实体名称
entity_type_name NVARCHAR2(1024),	-- 实体类型名称
operate_type INT,	-- 操作类型（操作类型：[1]查询；[2]新增；[3]更新；[4]删除）
db_schema NVARCHAR2(256),	-- 数据库架构
db_object_name NVARCHAR2(256),	-- 数据库对象名称
db_object_type INT,	-- 数据库对象类型（数据库对象类型：[1]数据表；[2]数据视图；[3]函数；[4]存储过程；[5]触发器）
db_object_key_field NVARCHAR2(256),	-- 主键字段
db_object_key_value NVARCHAR2(256),	-- 主键值
db_object_content NCLOB	-- 数据库对象内容，JSON格式
)
is
	code INT;   -- 操作返回编号，当 code<>0 时，系统将阻止提交，并返回 message 内容
	message NCLOB;   -- 操作返回消息
begin
    code := 0;
  	message := '';

	--------------------------------------------------------------------------------------------------------------------------------
	--	在分割线下方增加您的逻辑代码，并在判定 code<>0 时，使用 SELECT code,message 语句返回。
	--------------------------------------------------------------------------------------------------------------------------------

	--SELECT JSON_TABLE(JSON_DATAGUIDE(db_object_content) COLUMNS(Field1, Field2));

	--------------------------------------------------------------------------------------------------------------------------------
	--	返回操作结果。
	--------------------------------------------------------------------------------------------------------------------------------
    SELECT code,message;
end;";
                    break;
            }
            return script;
        }

        /// <summary>
        /// 获取更新脚本
        /// </summary>
        /// <param name="databaseType">数据库类型</param>
        /// <returns>更新脚本字符串</returns>
        protected override string GetUpdateScript(DatabaseType databaseType)
        {
            var script = string.Empty;
            switch (databaseType)
            {
                case DatabaseType.Sqlite:
                    break;
                case DatabaseType.MySql:
                    break;
                case DatabaseType.SqlServer:
                    break;
                case DatabaseType.PostgreSql:
                    break;
                case DatabaseType.Oracle:
                    break;
            }
            return script;
        }

        #endregion
    }
}